package cn.e4j.modular.system.service.impl;

import cn.e4j.core.cache.CacheKey;
import cn.e4j.core.cache.CacheUtil;
import cn.e4j.core.common.exception.BizExceptionEnum;
import cn.e4j.core.dto.Dtos;
import cn.e4j.core.dto.impl.Dto;
import cn.e4j.core.shiro.ShiroKit;
import cn.e4j.core.shiro.ShiroUser;
import cn.e4j.core.util.InvokeUtil;
import cn.e4j.core.util.TreeUtil;
import cn.e4j.model.exception.ServiceException;
import cn.e4j.modular.common.entity.SysOrgT;
import cn.e4j.modular.system.entity.SysOrg;
import cn.e4j.modular.system.mapper.SysOrgMapper;
import cn.e4j.modular.system.service.SysOrgService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 组织资料表 服务实现类
 * </p>
 *
 * @author wenchuan.li
 * @since 2018-12-09
 */
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements SysOrgService {

    @Transactional(readOnly = true)
    public List<SysOrg> getOrgsTree (){
        ShiroUser shiroUser = ShiroKit.getUser();
        if("2".equals(shiroUser.getTYPE())||"0".equals(shiroUser.getSysOrgT().getPARENT_ID())){
            return this.baseMapper.getOrgs(null);
        }else{
            Dto dto=Dtos.newDto();
            dto.put("ORG_ID",shiroUser.getORG_ID());
            //return this.baseMapper.getOrgsTreeLow(dto);
            return InvokeUtil.invokeBeanMethod("sysOrgMapper,getOrgsTreeLow",dto);
        }
    }

    @Transactional(readOnly = true)
    public List<Map<String, Object>> getOrgsList(Page<Object> page, Dto dto) {
        List<Map<String, Object>> orgDtos = this.baseMapper.listOrgsPage(page, dto);
        return orgDtos;
    }

    /**
     * 增加
     * @param sysOrg
     * @return
     */
    @Transactional
    public Dto add(SysOrg sysOrg){
        // 生成语义ID
        SysOrg parentSysOrg = this.baseMapper.getParentOrg(sysOrg.getPARENT_ID());
        String maxCascadeId = this.baseMapper.getMaxCascadeId(sysOrg.getPARENT_ID());
        if (maxCascadeId==null) {
            String temp = "0";
            if (parentSysOrg != null) {
                temp = parentSysOrg.getCASCADE_ID();
            }
            maxCascadeId = temp + ".000";
        }
        String cascade_id_ = TreeUtil.genCascadeTreeId(maxCascadeId, 999);
        sysOrg.setCASCADE_ID(cascade_id_);
        sysOrg.setIS_DEL("0");
        sysOrg.setIS_LEAF("1");
        sysOrg.insert();

        //更新父节点的是否叶子节点字段
        parentSysOrg.setIS_LEAF("0");
        parentSysOrg.updateById();

        //更新缓存
        CacheUtil.remove("'" + CacheKey.C_SYS_ORG_GETORGSTREE + "'");
        //新的node节点
        Dto item = Dtos.newDto();
        item.put("id", sysOrg.getID());
        item.put("name", sysOrg.getNAME());
        item.put("parentid", sysOrg.getPARENT_ID());
        item.put("code",sysOrg.getCASCADE_ID());
        Dto node = Dtos.newDto();
        node.put("node",item);
        return node;
    }

    /**
     * 修改
     * @param sysOrg
     */
    @Transactional
    public void edit(SysOrg sysOrg){
        SysOrgT oldSysOrg = this.baseMapper.getByID(sysOrg.getID());
        // 判断上级节点是否被更换
        if(oldSysOrg.getPARENT_ID().equals(sysOrg.getPARENT_ID())) {
            sysOrg.updateById();
            //更新缓存
            CacheUtil.remove("'" + CacheKey.C_SYS_ORG_GETORGSTREE + "'");
        } else {
            // 获取所有下级组织信息（ID和级联ID）
            List<SysOrg> childList = this.baseMapper.getOrgsTreeLowCascadeId(sysOrg.getID());

            // 生成语义ID
            String cascade_id_ = generateCascadeId(sysOrg.getPARENT_ID());

            // 更新所有下级组织的语义ID
            childList.forEach(node -> {
                String oldCascadeId = node.getCASCADE_ID();
                String newCascadeId = cascade_id_ + oldCascadeId.substring(oldCascadeId.lastIndexOf("."));
                node.setCASCADE_ID(newCascadeId);
            });
            sysOrg.setCASCADE_ID(cascade_id_);


            if(this.baseMapper.getChildList(sysOrg.getPARENT_ID()).size() == 0) {
                updateIsLeaf(sysOrg.getPARENT_ID(),"0");
            }

            sysOrg.updateById();
            childList.forEach(this::updateCascadeID);


            if(this.baseMapper.getChildList(oldSysOrg.getPARENT_ID()).size() == 0) {
                updateIsLeaf(oldSysOrg.getPARENT_ID(),"1");
            }
        }
    }

    private void updateIsLeaf(String ID,String isLeaf) {
        UpdateWrapper<SysOrg> sysOrgUpdateWrapper = new UpdateWrapper<>();
        sysOrgUpdateWrapper.eq("ID",ID);
        SysOrg updateSysOrg = new SysOrg();
        updateSysOrg.setIS_LEAF(isLeaf);
        updateSysOrg.update(sysOrgUpdateWrapper);
    }

    private void updateCascadeID(SysOrg sysOrg) {
        UpdateWrapper<SysOrg> sysOrgUpdateWrapper = new UpdateWrapper<>();
        sysOrgUpdateWrapper.eq("ID",sysOrg.getID());
        sysOrg.update(sysOrgUpdateWrapper);
    }

    private String generateCascadeId(String parentId) {
        SysOrg parentSysOrg = this.baseMapper.getParentOrg(parentId);
        String maxCascadeId = this.baseMapper.getMaxCascadeId(parentId);
        if (maxCascadeId==null) {
            String tempParentCascadeId = "0";
            if (parentSysOrg != null) {
                tempParentCascadeId = parentSysOrg.getCASCADE_ID();
            }
            maxCascadeId = tempParentCascadeId + ".000";
        }
        return TreeUtil.genCascadeTreeId(maxCascadeId, 999);
    }
    
    /**
     * 删除
     * @param sysOrg
     */
    @Transactional
    public void delete(SysOrg sysOrg){
        //更新父节点的是否叶子节点属性
        List childList = this.baseMapper.getChildList(sysOrg.getID());
        if(childList.size()==0){
            //edit by 20200109 不删除数据，只更新is_del
            //sysOrg.deleteById();
            sysOrg.setIS_DEL("1");
            sysOrg.updateById();

            List parentChildList = this.baseMapper.getChildList(sysOrg.getPARENT_ID());
            if(parentChildList.size() == 0){
                SysOrg parentSysOrg = this.baseMapper.getParentOrg(sysOrg.getPARENT_ID());
                parentSysOrg.setIS_LEAF("1");
                parentSysOrg.updateById();
            }
        }
        //更新缓存
        CacheUtil.remove("'" + CacheKey.C_SYS_ORG_GETORGSTREE + "'");
    }

    public List getChildList(SysOrg sysOrg) {
        List childList = this.baseMapper.getChildList(sysOrg.getID());
        return childList;
    }

}
